// Copyright (c) 2021 Presto Labs Pte. Ltd.
// Author: hyuan

#pragma once

#include <memory>
#include <string>
#include <unordered_map>

#include "coin2/exchange/base/order/order.h"
#include "coin2/exchange/order/gateio.pb.h"

enum GateioFuturesOrderSubTopicId : int {
  UNKNOWN_GateioFuturesOrderSubTopicId = -1,
  REST_TRADING_FEE = 10000
};

class GateioFuturesNativePrivateClient : public coin2::exchange::base::order::NativePrivateClient {
 public:
  using RestParams = coin2::exchange::order::GateioFuturesRestParams;
  using NativeClientConfig = coin2::exchange::order::OrderConnectionConfig;
  using HttpContextPtr = std::shared_ptr<AsioHttpContext>;

 public:
  std::shared_ptr<AsioHttpContext> SubmitOrderExecution(const OrderExecutionProto& order);
  std::shared_ptr<AsioHttpContext> SubmitRestQuery(const RestQueryProto& query);

 public:
  explicit GateioFuturesNativePrivateClient(
      const MarketExchangeApi& mea,
      const NativeClientConfig& config,
      bool is_delivery);

  HttpContextPtr QueryAccountBalance(const RestParams& params);
  HttpContextPtr QueryAccountPosition(const RestParams& params);
  HttpContextPtr QueryOpenOrders(const RestParams& params);
  HttpContextPtr QueryHistOrders(const RestParams& params);
  HttpContextPtr QueryHistTrades(const RestParams& params);
  HttpContextPtr QueryTradingFee();

  HttpContextPtr PlaceOrder(const RestParams& params);
  HttpContextPtr CancelOrder(const RestParams& params);
  HttpContextPtr PlaceOrderNorm(const OrderExecution&) override;
  HttpContextPtr CancelOrderNorm(const OrderExecution&) override;

  RestParams GetRestOrderParams(const OrderSpec& order_spec, int64_t proc_order_id);
  RestParams GetRestCancelParams(const IOrderContext& order_context);

  std::string DebugString() const;

  void Prepare();

  void SetUserId(const std::string& channel, void* data);

 private:
  int64_t start_time_;
  std::unordered_map<std::string, int32_t> api_block_info_;
  std::unordered_map<std::string, int32_t> api_req_info_;
  bool is_user_id_ready_ {false};
  bool is_delivery_;

 private:
  const std::string path_query_trading_fee_ = "/api/v4/wallet/fee";
  std::string path_query_account_balance_;
  std::string path_query_account_position_;
  std::string path_query_open_orders_;
  std::string path_query_hist_orders_;
  std::string path_query_hist_trades_;
  std::string path_place_order_;
  std::string path_cancel_order_;
};
